home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
os2
/
eaclib.zip
/
EALIST.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-22
|
21KB
|
637 lines
/* --------------------------------------------------------------------------
* $RCSfile: EAList.cpp,v $
* $Revision: 1.1 $
* $Date: 1996/05/22 20:59:55 $
* $Author: Bablok $
* --------------------------------------------------------------------------
* Synopsis:
*
* Implementation of class EAList. This class wraps the extended attributes API
* of OS/2 and handles complete sets of file-EAs.
*
* An EAList is implemented as a key sorted set. This allows the conversion
* of an EAList to a multivalued EA and back again.
*
* This file is part of the EA classlib package.
* Copyright Bernhard Bablok, 1996
*
* The EA classlib package is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You may use the classes in the package to any extend you wish. You are
* allowed to change and copy the source of the classes, as long as you keep
* the copyright notice intact and as long as you document the changes you made.
*
* You are not allowed to sell the EA classlib package or a modified version
* thereof, but you may charge for costs of distribution media.
*
* --------------------------------------------------------------------------
* Change-Log:
*
* $Log: EAList.cpp,v $
* Revision 1.1 1996/05/22 20:59:55 Bablok
* Initial revision
*
* -------------------------------------------------------------------------- */
#ifndef _IEXCEPT_
#include <iexcept.hpp>
#endif
#ifndef _IMSGTEXT_
#include <imsgtext.hpp>
#endif
#ifndef __iostream_h
#include <iostream.h>
#endif
#ifndef __math_h
#include <math.h>
#endif
#ifndef EA_H
#include "EA.hpp"
#endif
#ifndef EALIST_H
#include "EAList.hpp"
#endif
///////////////////////////////////////////////////////////////////////////////
// Copy constructor
//
EAList::EAList(const EAList& eaList) : EASet(EALIST_DEFAULT_SIZE),
mFEA2List(NULL) {
if (eaList.mFEA2List) {
ULONG length = *(ULONG*) eaList.mFEA2List;
char *buffer = new char[length];
if (!buffer) {
IOutOfMemory exc(IMessageText(ERR_MEM_ALLOC_FAILED,MSG_FILE),0);
ITHROW(exc);
}
memcpy(buffer,(char*) eaList.mFEA2List,length);
mFEA2List = (FEA2LIST*) buffer;
}
addAllFrom(eaList);
}
///////////////////////////////////////////////////////////////////////////////
// Construct EAList from multi-valued EA
//
EAList::EAList(const IString& basename, const EA& ea) :
EASet(EALIST_DEFAULT_SIZE), mFEA2List(NULL) {
USHORT type,
n = ea.numValues(), // this will throw an exception if not mv
digits = log10(n) + 1;
BYTE flag = ea.flag();
char *p = (char*) ea.value() + 2*sizeof(USHORT); // skip header
// extract type if single-typed -------------------------------------------
if (ea.type() == EAT_MVST) {
type = *(USHORT*) p;
p += sizeof(USHORT);
if (!EA::isLengthPreceded(type)) {
IString excText(IMessageText(ERR_INVALID_TYPE,MSG_FILE));
excText += " (" + EA::typeAsString(type) + ")";
IInvalidRequest exc(excText,0,IException::recoverable);
ITHROW(exc);
}
}
// iterate through all entries --------------------------------------------
for (int i=1; i<=n; ++i) {
if (ea.type() == EAT_MVMT) {
type = *(USHORT*) p;
p += sizeof(USHORT);
if (!EA::isLengthPreceded(type)) {
IString excText(IMessageText(ERR_INVALID_TYPE,MSG_FILE));
excText += " (" + EA::typeAsString(type) + ")";
IInvalidRequest exc(excText,0,IException::recoverable);
ITHROW(exc);
}
}
USHORT length = *(USHORT*) p;
p += sizeof(USHORT);
IString name = basename + IString('.') + IString(i).rightJustify(digits,0);
add(EA(name,p,length,type,flag));
p += length;
}
}
///////////////////////////////////////////////////////////////////////////////
// Assignment
//
EAList& EAList::operator=(const EAList& eaList) {
if (&eaList == this)
return *this;
if (mFEA2List)
delete mFEA2List;
if (eaList.mFEA2List) {
ULONG length = *(ULONG*) eaList.mFEA2List;
char *buffer = new char[length];
if (!buffer) {
IOutOfMemory exc(IMessageText(ERR_MEM_ALLOC_FAILED,MSG_FILE),0);
ITHROW(exc);
}
memcpy(buffer,(char*) eaList.mFEA2List,length);
mFEA2List = (FEA2LIST*) buffer;
} else
mFEA2List = NULL;
removeAll();
addAllFrom(eaList);
return *this;
}
///////////////////////////////////////////////////////////////////////////////
// Read EAs from a given file. This function either reads all EAs of the
// file, or only the EAs given in the list.
//
EAList& EAList::read(PVOID fileRef,Boolean isPathName,Boolean onlyEAsFromList) {
EAOP2 eaBuffer;
eaBuffer.oError = 0;
if (onlyEAsFromList) {
if (!numberOfElements()) // nothing to do!
return *this;
eaBuffer.fpGEA2List = createGEA2LIST();
eaBuffer.fpFEA2List = createFEA2LISTBuffer(fileRef,isPathName);
} else {
DENA2 *eaEnumBuffer = queryDENA2(fileRef,isPathName);
if (!eaEnumBuffer) {
removeAll();
return *this;
}
eaBuffer.fpGEA2List = createGEA2LIST(eaEnumBuffer);
eaBuffer.fpFEA2List = createFEA2LISTBuffer(eaEnumBuffer);
delete eaEnumBuffer;
}
APIRET rc;
if (isPathName)
rc = DosQueryPathInfo((PSZ)fileRef,FIL_QUERYEASFROMLIST,
&eaBuffer,sizeof(EAOP2));
else
rc = DosQueryFileInfo(*(HFILE*)fileRef,FIL_QUERYEASFROMLIST,
&eaBuffer,sizeof(EAOP2));
delete eaBuffer.fpGEA2List;
if (rc) {
IString api;
if (isPathName)
api = "DosQueryPathInfo";
else
api = "DosQueryFileInfo";
IException exc(ISystemErrorInfo(rc,api),rc,IException::recoverable);
ITHROW(exc);
}
if (!onlyEAsFromList)
removeAll(); // this is save now
return convert(); // converts FEA2LIST to EAList
}
///////////////////////////////////////////////////////////////////////////////
// Write EAs to a given file.
//
EAList& EAList::write(PVOID fileRef,Boolean isPathName,Boolean useFEA2List) {
if (!numberOfElements()) // nothing to do!
return *this;
EAOP2 eaBuffer;
eaBuffer.oError = 0;
eaBuffer.fpGEA2List = 0;
if (useFEA2List)
eaBuffer.fpFEA2List = mFEA2List;
else
eaBuffer.fpFEA2List = createFEA2LIST();
APIRET rc;
if (isPathName)
rc = DosSetPathInfo((PSZ)fileRef,FIL_QUERYEASIZE,&eaBuffer,sizeof(EAOP2),
DSPI_WRTTHRU);
else
rc = DosSetFileInfo(*(HFILE*)fileRef,FIL_QUERYEASIZE,
&eaBuffer,sizeof(EAOP2));
if (rc) {
IString api;
if (isPathName)
api = "DosSetPathInfo";
else
api = "DosSetFileInfo";
IException exc(ISystemErrorInfo(rc,api),rc,IException::recoverable);
ITHROW(exc);
}
return *this;
}
///////////////////////////////////////////////////////////////////////////////
// Remove EAs from a given file. This function either removes all EAs of the
// file, or only the EAs given in the list.
//
EAList& EAList::remove(PVOID fileRef,Boolean isPathName,Boolean onlyEAsFromList) {
EAList removeList;
if (onlyEAsFromList)
removeList = *this;
else
removeList.read(fileRef,isPathName,false);
EAList::Cursor current(removeList);
forCursor(current)
removeList.elementAt(current).setValue("");
removeList.write(fileRe